package com.tools.web.interceptor.auth;

import com.tools.common.object.Note;
import com.tools.common.thread.TimePair;
import com.tools.common.thread.Timeunit;
import org.slf4j.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 简单机制 实现 AuthToken 续期的实现类
 * */
@Note("简单机制 实现 AuthToken 续期的实现类")
public final class SimpleAuthTokenExtender implements AuthTokenExtender{

    @Note("token 每次续期续多长时间。单位毫秒")
    private final long extendTimeMill;

    @Note("现在 - 过期时间 < 该值，就允许续期。单位毫秒")
    private final long maxAllowExtendTimeMill;

    @Note("在 maxAllowExtendTime 的期限内，允许续期多少次")
    private final int maxAllowExtendCount;

    /* **************************************************************************************
     *
     *          构造器
     *
     * **************************************************************************************
     * */

    public SimpleAuthTokenExtender(TimePair extendTime, TimePair maxAllowExtendTime, int maxAllowExtendCount) {
        if(extendTime != null && maxAllowExtendTime != null && maxAllowExtendCount > 0) {
            this.extendTimeMill = extendTime.toMill();
            this.maxAllowExtendTimeMill = maxAllowExtendTime.toMill();
            this.maxAllowExtendCount = maxAllowExtendCount;
            return;
        }
        this.extendTimeMill = 0;
        this.maxAllowExtendTimeMill = 0;
        this.maxAllowExtendCount = 0;
    }

    /* **************************************************************************************
     *
     *          Getter
     *
     * **************************************************************************************
     * */

    @Override
    public long getExtendTimeMill() {
        return extendTimeMill;
    }

    @Override
    public long getMaxAllowExtendTimeMill() {
        return maxAllowExtendTimeMill;
    }

    @Override
    public int getMaxAllowExtendCount() {
        return maxAllowExtendCount;
    }

    @Override
    public String toString() {
        return "SimpleAuthTokenExtender{" +
                "extendTimeMill=" + extendTimeMill +
                ", maxAllowExtendTimeMill=" + maxAllowExtendTimeMill +
                ", maxAllowExtendCount=" + maxAllowExtendCount +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SimpleAuthTokenExtender that = (SimpleAuthTokenExtender) o;
        return extendTimeMill == that.extendTimeMill && maxAllowExtendTimeMill == that.maxAllowExtendTimeMill && maxAllowExtendCount == that.maxAllowExtendCount;
    }

    @Override
    public int hashCode() {
        return Objects.hash(extendTimeMill, maxAllowExtendTimeMill, maxAllowExtendCount);
    }

    /* **************************************************************************************
     *
     *          功能方法
     *
     * **************************************************************************************
     * */

    @Override
    public boolean isEnable() {
        return extendTimeMill > 0
                && maxAllowExtendTimeMill > 0
                && maxAllowExtendCount > 0;
    }

    @Override
    public AuthTokenExtender copy() {
        TimePair timePair = new TimePair(this.extendTimeMill, Timeunit.MILL);
        TimePair maxAllowExtendTime = new TimePair(this.maxAllowExtendTimeMill, Timeunit.MILL);
        return new SimpleAuthTokenExtender(timePair, maxAllowExtendTime, this.maxAllowExtendCount);
    }

    @Override
    public boolean extend(HttpServletRequest request, HttpServletResponse response,
                          AuthenticationManager authenticationManager, Logger logger,
                          String encryptedAccessToken, AuthToken accessToken,
                          Timeunit timeunitUsedBySubclass) throws Exception {
        //现在 - 过期时间已经超过最大允许的续期时间，不允许再续期
        long now = System.currentTimeMillis();
        long oldExpirationMill = accessToken.getExpirationMill();
        if(now - oldExpirationMill >= this.maxAllowExtendTimeMill) {
            return false;
        }
        //如果已经续期的次数超过了最大允许阈值，也不允许续期
        int accessTokenExtendedCount = accessToken.getExtendedCount();
        if(accessTokenExtendedCount >= this.maxAllowExtendCount) {
            return false;
        }
        //续期
        int newExtendedCount = accessToken.getExtendedCount() + 1;
        accessToken.setExtendedCount(newExtendedCount);
        long newExpiration = now + this.extendTimeMill;
        accessToken.setExpirationMill(newExpiration, Timeunit.MILL);
        return true;
    }
}
